<template>
  <a-popover
    v-model:open="visible"
    trigger="click"
    placement="bottomLeft"
    :align="{ offset: [0, 0] }"
    :get-popup-container="bindParent ? (triggerNode) => triggerNode.parentNode : null"
    @open-change="(open) => onOpenChange(open)"
  >
    <template #content>
      <a-spin :spinning="loading">
        <div class="w-[560px] min-h-[200px] max-h-[400px] overflow-y-auto overflow-x-hidden flex flex-col justify-between">
          <div ref="tagBoxRef" class="px-2 pb-1 tag-box">
            <div v-for="tag in tagsList" :key="tag" class="tag-item inline-block mt-2" :class="tagClass">
              <a-tag v-if="closable" closable @close="handleDelete(tag)">
                <span class="text-sm whitespace-nowrap">{{ tag[config.labelKey] }}</span>
              </a-tag>
              <a-checkable-tag v-else :checked="tag.isChecked" @change="(checked) => onSelectTag(tag, checked)">
                <span class="text-sm whitespace-nowrap">{{ tag[config.labelKey] }}</span>
              </a-checkable-tag>
            </div>
            <template v-if="showNew">
              <a-input
                v-if="inputVisible"
                ref="newInputRef"
                v-model:value="newInputValue"
                type="text"
                placeholder="请输入"
                size="small"
                class="w-[200px] mt-2"
                @blur="onAddTag"
                @keyup.enter="onAddTag"
              />
              <a-tag v-else class="bg-thin border-dashed mt-2" @click="showInput">
                <PlusOutlined />
                新标签
              </a-tag>
            </template>
          </div>
          <div class="py-2 px-4 flex justify-between bg-thin items-center">
            <div>
              <a-input-search v-model:value="zjm" placeholder="输入部位助记码" @search="queryData" />
              <a-button v-if="showSetting" type="link" size="small" @click="onSetting">配置</a-button>
            </div>
            <a-button danger type="link" size="small" @click="visible = false">关闭</a-button>
          </div>
        </div>
      </a-spin>
    </template>
    <div v-if="inputOrTextarea" class="h-full relative">
      <a-input
        ref="inputRef"
        v-model:value="inputValue"
        :placeholder="placeholder"
        :bordered="bordered"
        :disabled="disabled"
        :class="inputClass"
        @focus="onFocus"
        @blur="onBlur"
        @change="onInputChange"
      >
        <template v-if="showSuffix" #suffix>
          <DownOutlined :style="{ color: '#00000040', fontSize: '12px' }" />
        </template>
      </a-input>
      <slot name="addonAfter"> </slot>
    </div>
    <div v-else class="relative">
      <a-textarea
        ref="inputRef"
        v-model:value="inputValue"
        :placeholder="placeholder"
        :bordered="bordered"
        :disabled="disabled"
        :rows="rowVal"
        :class="inputClass"
        @focus="onFocus"
        @blur="onBlur"
        @change="onInputChange"
      >
        <template v-if="showSuffix" #suffix>
          <DownOutlined :style="{ color: '#00000040', fontSize: '12px' }" />
        </template>
      </a-textarea>
      <slot name="addonAfter"> </slot>
    </div>
  </a-popover>
</template>

<script setup>
/**
 * @name:在Tags中选择项目
 */
import { ref, watch, nextTick, reactive, onMounted } from 'vue'
import { DownOutlined, PlusOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import { post } from '@/utils/request'
import { getSelectTagsConfig } from './config'

const loading = ref(false)
const visible = ref(false)
const closable = ref(false)
const inputVisible = ref(false)
const tagsList = ref([])
const inputRef = ref()
const tagBoxRef = ref()
const newInputRef = ref()
const newInputValue = ref()
const zjm = ref('')

const inputValue = ref(null) //页面展示的值

const emit = defineEmits(['update:value', 'select', 'close', 'blur'])
const props = defineProps({
  value: {
    type: Object,
    default: () => ({})
  },
  valueObject: {
    type: Boolean,
    desc: 'value数据类型是否为对象',
    default: false
  },
  placeholder: {
    type: String,
    default: '请输入'
  },
  type: {
    type: String,
    required: true,
    default: ''
  },
  tagClass: {
    type: String,
    default: ''
  },
  bindParent: {
    desc: '绑定到父元素',
    type: Boolean,
    default: false
  },
  bordered: {
    type: Boolean,
    default: true
  },
  disabled: {
    type: Boolean,
    default: false
  },
  defaultOpen: {
    desc: '是否默认打开',
    type: Boolean,
    default: false
  },
  multiple: {
    desc: '是否多选，多选模式下不支持对象value',
    type: Boolean,
    default: false
  },
  showSuffix: {
    desc: '是否显示下拉图标',
    type: Boolean,
    default: false
  },
  showNew: {
    desc: '是否显示新标签',
    type: Boolean,
    default: false
  },
  trigger: {
    desc: '请求数据时机init:初始化/focus:聚焦',
    type: String,
    default: 'focus'
  },
  selectFirst: {
    desc: '是否默认选择第一个',
    type: Boolean,
    default: false
  },
  showSetting: {
    desc: '是否显示配置按钮',
    type: Boolean,
    default: false
  },
  searchParams: {
    desc: '搜索条件',
    type: Object,
    default: () => ({})
  },
  inputOrTextarea: {
    desc: '输入框或者文本框',
    type: Boolean,
    default: true
  },
  rowVal: {
    desc: '文本框',
    type: Number,
    default: 2
  },
  inputClass: {
    type: String,
    default: ''
  },
  inputAddonAfterShow: {
    type: Boolean,
    default: false
  }
})
const partCode = ref([])
const config = reactive(getSelectTagsConfig(props.type))
const onFocus = () => {
  if (props.inputOrTextarea) inputRef.value.setSelectionRange(0, 200)
  props.trigger === 'focus' && queryData()
}
const onBlur = (event) => {
  if (!event.target.value && isChange.value) {
    setDataEmpty()
    partCode.value = []
    emit('select', { partCode: partCode.value, partName: inputValue.value })
  }
  emit('blur', inputValue.value)
}

watch(
  () => props.value,
  (value) => {
    if (value?.partCode) {
      inputValue.value = value?.partName
      partCode.value = value?.partCode
    } else {
      inputValue.value = ''
      partCode.value = []
    }
  },
  { immediate: true }
)

const onSelectTag = (tag, checked) => {
  tag.isChecked = checked
  if (props.multiple && props.valueObject) return message.error('多选模式下不支持对象value')
  if (props.multiple) {
    //多选
    if (inputValue.value) {
      if (partCode.value.includes(tag.id)) {
        partCode.value = partCode.value.filter((item) => item !== tag.id)
        //判断inputValue.value里面含有tag.partName的一项和逗号删除
        let arr = inputValue.value.split(',')
        if (arr.includes(tag.partName)) {
          arr = arr.filter((item) => item !== tag.partName)
          if (arr.length > 0) {
            inputValue.value = arr.join(',')
          } else {
            inputValue.value = ''
          }
        }
      } else {
        partCode.value.push(tag.id)
        inputValue.value = inputValue.value + ',' + tag.partName
      }
    } else {
      inputValue.value = tag.partName
      partCode.value = [tag.id]
    }
    judgeChecked()
    emit('select', { partCode: partCode.value, partName: inputValue.value })
    isChange.value = true
  } else {
    //单选
    visible.value = false
    partCode.value = [tag.id]
    inputValue.value = props.valueObject ? tag : tag[config.labelKey]
    emit('select', { partCode: partCode.value, partName: inputValue.value })
    isChange.value = true
  }
}
const isChange = ref(false)

const onInputChange = () => {
  isChange.value = true
  // if (!event.target.value) {
  //   setDataEmpty()
  //   partCode.value = []
  //   emit('select', partCode.value)
  // }
  // emit('update:value', inputValue.value)
}

//获取数据
const queryData = async () => {
  loading.value = true
  const { url, params } = config
  const { data = [] } = await post(url, { ...params, ...props.searchParams, zjm: zjm.value })
  tagsList.value = data
  loading.value = false
  props.selectFirst && onSelectTag(data[0])
  judgeChecked()
  setTimeout(() => setFirstTagLine(), 10)
}

const setFirstTagLine = () => {
  const box = tagBoxRef.value
  const children = box?.children || []
  let currentTop = null
  for (let i = 0; i < children.length; i++) {
    const child = children[i]
    const childTop = child.offsetTop
    if (childTop !== currentTop) {
      currentTop = childTop
      child.classList.add('tag-line-first')
    }
  }
}
//------------------------配置操作start
const handleDelete = async (removedTag) => {
  const res = await post('/outp/template/doDelOutpEMRWord', {
    blcybh: removedTag.bh
  })
  if (res.code !== 0) return message.error(res.msg || '操作失败')
  message.success(res.msg)
  queryData()
}

const showInput = () => {
  inputVisible.value = true
  nextTick(() => {
    newInputRef.value.focus()
  })
}
const onSetting = () => {
  closable.value = !closable.value
}

const onAddTag = async () => {
  if (newInputValue.value) {
    const res = await post('/operation/opex/doSaveDictPart', {
      partName: newInputValue.value
    })
    if (res.code !== 0) return message.error(res.msg || '新增失败')
    newInputValue.value = ''
    queryData()
    message.success(res.msg || '新增成功')
  }
  inputVisible.value = false
  // inputValue.value = ''
}
const setDataEmpty = () => {
  tagsList.value = tagsList.value.map((item) => {
    item.isChecked = false
    return item
  })
}
//判断tagsList里面是否存在partCode
const judgeChecked = () => {
  if (partCode.value.length > 0) {
    tagsList.value.forEach((item) => {
      if (partCode.value.includes(item.id)) {
        item.isChecked = true
      }
    })
  }
}
//------------------------end
const onOpenChange = (open) => {
  if (!open) {
    emit('close', open)
  }
  isChange.value = false
  zjm.value = ''
}
//自动展开
watch(
  () => props.defaultOpen,
  (value) => {
    if (value) {
      inputRef.value.focus()
      visible.value = true
    }
  }
)
onMounted(() => {
  props.trigger === 'init' && queryData()
})
</script>
<style lang="less" scoped>
.ant-tag {
  padding: 2px 12px;
  white-space: break-spaces;
  word-wrap: break-word;
  word-break: break-all;
  &:hover {
    color: var(--primary-color);
    background: var(--secondary-color);
  }
}
.placeholder {
  color: rgba(0, 0, 0, 0.25);
  font-size: 12px;
}
.cell-style {
  padding: 4px 11px;
  border: 1px solid transparent;
  &:hover,
  &.focusd {
    border: 1px solid var(--primary-color);
  }
}
.tag-box {
  .tag-line-first {
    position: relative;
    &::after {
      position: absolute;
      bottom: -4px;
      left: -8px;
      width: 560px;
      height: 1px;
      background-color: #00000010;
      content: '';
    }
  }
}
</style>
